//
//  VideoSnapshotter.swift
//  JKTool
//
//  Created by 姜奎 on 2023/6/6.
//

import Foundation
import CoreGraphics
import AVFoundation

extension JKTool {
    struct VideoSnapshotter: ParsableCommand {
        static var configuration = CommandConfiguration(
            commandName: "videoSnapshot",
            _superCommandName: "jktool",
            abstract: "从mp4视频中获取帧图",
            version: "1.0.0"
        )
        
        @Option(name: .shortAndLong, help: "每秒输出张数。default：10")
        var delay: Int = 10
        
        @Option(name: .shortAndLong, help: "同时输出自动拼接的长图，default：false")
        var spliceLongGraph: Bool?
        
        @Option(name: .shortAndLong, help: "输出图片路径")
        var toPath: String
        
        @Option(name: .shortAndLong, help: "视频位置")
        var path: String

        mutating func run() {
            
            func videoSnapshot(images:[CGImage]){
                
                
                for (index,image) in images.enumerated() {
                    // 创建上下文并绘制图像
                    let width = image.width
                    let height = image.height
                    let colorSpace = CGColorSpaceCreateDeviceRGB()
                    let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue
                    guard let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: 8, bytesPerRow: 0, space: colorSpace, bitmapInfo: bitmapInfo) else {
                        return po(tip: "图片处理异常",type: .error)
                    }
                    context.draw(image, in: CGRect(x: 0, y: 0, width: width, height: height))

                    // 保存图像到磁盘
                    let outputURL = URL(fileURLWithPath: "\(toPath)/\(index).png")
                    guard let outputImage = context.makeImage() else {
                        return po(tip: "图片处理异常",type: .error)
                    }
                    let destination = CGImageDestinationCreateWithURL(outputURL as CFURL, kUTTypePNG, 1, nil)!
                    CGImageDestinationAddImage(destination, outputImage, nil)
                    CGImageDestinationFinalize(destination)
                    
                }
                
                guard spliceLongGraph == true,let first = images.first else { return }
                
                let width = first.width
                let height = first.height
                
                let totalWidth = width * images.count
                let totalHeight = height

                guard let context = CGContext(data: nil, width: totalWidth, height: totalHeight, bitsPerComponent: 8, bytesPerRow: 0, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else {
                    return po(tip: "图片处理异常",type: .error)
                }
                
                for (index,image) in images.enumerated() {
                    context.draw(image, in: CGRect(x: index * width, y: 0, width: width, height: height))
                }

                let mergedImage = context.makeImage()!

                // 保存合并后的图像到磁盘
                let outputURL = URL(fileURLWithPath: "\(toPath)/长图.png")
                let destination = CGImageDestinationCreateWithURL(outputURL as CFURL, kUTTypePNG, 1, nil)!
                CGImageDestinationAddImage(destination, mergedImage, nil)
                CGImageDestinationFinalize(destination)
                
            }
            
//            guard  else { return  po(tip: "视频路径有误(\(path))",type: .error) }
            let videoURL = URL(fileURLWithPath: path)
            
            let asset = AVAsset(url: videoURL)

            // 创建一个 AVAssetImageGenerator 实例，用于从视频中提取图像
            let imageGenerator = AVAssetImageGenerator(asset: asset)
            imageGenerator.requestedTimeToleranceAfter = .zero
            imageGenerator.requestedTimeToleranceBefore = .zero

            // 设置要输出的每秒帧数
            let duration = CMTimeGetSeconds(asset.duration)
            let frameCount = Int(duration) * delay

            var images = [CGImage]()
            // 遍历每一秒，提取帧图像
            for i in 0..<frameCount {
                let seconds = Double(i) / Double(delay)
                let time = CMTime(seconds: seconds, preferredTimescale: 600)
                var actualTime = CMTime.invalid
                if let image = try? imageGenerator.copyCGImage(at: time, actualTime: &actualTime) {
                    // 在这里处理所提取的图像，例如将其保存到磁盘上
                    // ...
                    images.append(image)
                }
            }
            
            guard images.isEmpty == false else {
                return po(tip: "获取到的图片帧为空",type: .error)
            }
            
            videoSnapshot(images: images)
        }
            
    }
}
